home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995…tember: Reference Library / Dev.CD Sep 95 RL / Dev.CD Sep 95 RL.toast / mac / Technical Documentation / develop / develop Issue 21 code / Hierarchical Lists / CMyDiskListBox.cp < prev    next >
Encoding:
Text File  |  1994-09-22  |  5.6 KB  |  192 lines  |  [TEXT/MMCC]

  1. // ===========================================================================
  2. //    CMyDiskListBox.h            ©1994 Jan Bruyndonckx All rights reserved.
  3. //    v1.0 18/6/94
  4. //
  5. //    A hierarchical demo listbox: displays the files on a volume (with icons)
  6. //
  7. // ===========================================================================
  8.  
  9. #include <files.h>
  10. #include <string.h>
  11. #include <strings.h>
  12. #include <lists.h>
  13. #include <resources.h>
  14. #include "UMemoryMgr.h"
  15. #include "CMyDiskListBox.h"
  16.  
  17. //----------------------------------------------------------------------------
  18.  
  19. typedef enum {        // our list can contain volumes, folders and files
  20.     tag_disk,
  21.     tag_folder,
  22.     tag_file
  23. } DiskTags ;
  24.  
  25. #if defined(powerc)
  26.  #pragma options align=mac68k
  27. #endif
  28.  
  29. typedef struct {
  30.     TwistDownHeader    hd ;
  31.     long            refNum ;
  32.     char            vRefNum ;        // yes, it should go in a byte…
  33.     Byte            tag ;
  34.     char            name[2] ;
  35. } DiskListRec, *DiskListPtr ;
  36.  
  37. #if defined(powerc)
  38.  #pragma options align=reset
  39. #endif
  40.  
  41. const Size DiskListRecSize = sizeof (DiskListRec)-2 ;    // don't count the name field
  42.  
  43. //----------------------------------------------------------------------------
  44. // Creation methods
  45.  
  46. CMyDiskListBox* CMyDiskListBox::CreateFromStream(LStream *inStream)
  47. {
  48.   return (new CMyDiskListBox(inStream));
  49. }
  50.  
  51. CMyDiskListBox::CMyDiskListBox (LStream *inStream) : CTwistDownListBox (inStream)
  52. { Cell cell = { -1, 0 } ;
  53.  
  54.   ExpandElement (cell) ;
  55. }
  56.  
  57. //----------------------------------------------------------------------------
  58. // Override this method from LPane.  So we get notified when the window gets wider,
  59. // and we can adapt our cell width accordingly.
  60.  
  61. void CMyDiskListBox::ResizeFrameBy (Int16 inWidthDelta, Int16 inHeightDelta,
  62.                                     Boolean inRefresh)
  63.   (*mMacListH)->cellSize.h += inWidthDelta ;
  64.   inherited::ResizeFrameBy (inWidthDelta, inHeightDelta, inRefresh) ;
  65. }
  66.  
  67. //----------------------------------------------------------------------------
  68. // Expand an element from the list.  This triggers a directory search and inserts
  69. // the items in the list.  For the top-level: get all the volumes.
  70.  
  71. void CMyDiskListBox::ExpandElement (const Cell theCell)
  72. { short                error, i; 
  73.   Cell                cell = theCell ;
  74.   Byte                buffer[100] ;
  75.   DiskListPtr        thisTwist = (DiskListPtr) GetCellPtr (theCell) ;
  76.   DiskListPtr        anElement = (DiskListPtr) buffer ;
  77.   
  78.   if (thisTwist == NULL)                        // this function is first called -> top level = volumes
  79.       { 
  80.         for (i = 1 ; ; i++)
  81.           { HParamBlockRec    block ;
  82.           
  83.           block.volumeParam.ioNamePtr  = (StringPtr) anElement->name;    //    the name…
  84.           block.volumeParam.ioVRefNum  = 0;                    //    0 means use ioVolIndex
  85.           block.volumeParam.ioVolIndex = i;
  86.  
  87.           error = ::PBHGetVInfoSync (&block);    
  88.           if (error)
  89.               break ;
  90.     
  91.           ::PtoCstr ((StringPtr) anElement->name) ;
  92.           anElement->tag        = tag_disk ;
  93.           anElement->vRefNum    = block.volumeParam.ioVRefNum ;
  94.           anElement->refNum        = fsRtDirID ;
  95.             anElement->hd.indent  = 0 ;
  96.             anElement->hd.flags   = kHasSubList ;
  97.           
  98.            cell.v = ::LAddRow (1, 32000, mMacListH) ;
  99.               ::LSetCell (anElement, sizeof (DiskListRec) - 2 + strlen((char*) anElement->name), cell, mMacListH) ;
  100.             }
  101.  
  102.         return ;
  103.       }
  104.       
  105.   short    vRefNum = thisTwist->vRefNum ;
  106.   long  parID    = thisTwist->refNum ;
  107.   short indent  = thisTwist->hd.indent+1 ;
  108.   
  109.   for (i = 1, cell.v++ ; ; i++, cell.v++)
  110.     { CInfoPBRec    block;
  111.     
  112.       block.dirInfo.ioNamePtr   = (StringPtr) anElement->name ;
  113.       block.dirInfo.ioVRefNum   = vRefNum;
  114.       block.dirInfo.ioFDirIndex = i;
  115.       block.dirInfo.ioDrDirID   = parID;
  116.  
  117.       error = ::PBGetCatInfoSync (&block) ;
  118.       if (error)
  119.         break ;
  120.         
  121.       ::PtoCstr ((StringPtr) anElement->name) ;
  122.       anElement->vRefNum    = vRefNum ;
  123.         anElement->hd.indent  = indent ;
  124.       if ((block.dirInfo.ioFlAttrib & 0x10) != 0)    // is a directory
  125.          { anElement->tag        = tag_folder ;
  126.           anElement->refNum        = block.dirInfo.ioDrDirID ;
  127.             anElement->hd.flags   = kHasSubList ;
  128.          }
  129.       else                                            // is a file
  130.          { anElement->tag        = tag_file ;
  131.           anElement->refNum        = 0 ;
  132.             anElement->hd.flags   = 0 ;
  133.          }
  134.          
  135.       cell.v = ::LAddRow (1, cell.v, mMacListH) ;
  136.         ::LSetCell (anElement, sizeof (DiskListRec) - 2 + strlen((char*) anElement->name), cell, mMacListH) ;
  137.     }
  138. }
  139.  
  140. //----------------------------------------------------------------------------
  141.  
  142. static void PlotSICN (Rect *rect, Handle sicnList)
  143.  
  144. // Draw the icon for a list element
  145.  
  146. { GrafPtr    port ;
  147.   char        saveState = ::HGetState ((Handle) h) ;
  148.   ::HLock ((Handle) h) ;
  149.  
  150.   BitMap    srcBits = { *sicnList, 2, { 0, 0, 16, 16 }};    // baseAddr, rowBytes, bounds
  151.  
  152.   ::GetPort (&port) ;
  153.   ::CopyBits (&srcBits, &(*port).portBits, 
  154.                 &srcBits.bounds, rect, 
  155.                 srcCopy, NULL) ;
  156.                 
  157.   ::HSetState ((Handle) h, saveState) ;
  158. }
  159.  
  160. //----------------------------------------------------------------------------
  161. // Be lazy and get the little icons from the System file.  If I'd design my own,
  162. // I'd make them a little smaller and use Geneva 9 for the text
  163.  
  164. const short sicnID[] = {
  165.     -3995,        //    tag_disk
  166.     -3999,        //    tag_folder,
  167.     -4000        //    tag_file
  168. } ;
  169.  
  170. void CMyDiskListBox::DrawTwistedElement (const Rect *lRect, 
  171.                                        const TwistDownRecPtr lElement,
  172.                                        const short lDataLen)
  173.                                        
  174. // Draw contents of a single list element, including icon.
  175.  
  176. { Point    pen ;
  177.  
  178.   ::GetPen (&pen) ;
  179.  
  180.   Handle h = ::GetResource ('SICN', sicnID[DiskListPtr(lElement)->tag]) ;
  181.   if (h != NULL)
  182.     { Rect box = { lRect->top-2, pen.h, lRect->top+16-2, pen.h+16 } ;
  183.       ::PlotSICN (&box, h) ;
  184.     }
  185.   
  186.   ::Move (21, 0) ;
  187.   ::DrawText (DiskListPtr(lElement)->name, 0, lDataLen-DiskListRecSize) ;
  188. }
  189.  
  190. //----------------------------------------------------------------------------
  191.